feat: implement Secret Rotation Service (Issue #119)#136
Merged
JamesEjembi merged 1 commit intoJul 22, 2026
Conversation
- Add SecretRotationService with rotation scheduling, zero-downtime overlap, expiry monitoring, and revocation - Add types for SecretRecord, RotationPolicy, RotationEvent, etc. - Add Node unit tests (13 tests) and browser benchmark (P99 0.45ms < 100ms) - Add Playwright E2E spec for CI validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #119
Overview
This PR implements a Secret Rotation Service for Database Credentials and API Keys as a first-class module in the VeriNode frontend. The service provides a secure, auditable, and observable foundation for rotating sensitive credentials at the client layer, with zero-downtime guarantees and comprehensive monitoring hooks.
The implementation is framework-agnostic (pure TypeScript) so it can be consumed by Next.js routes, API handlers, and client-side state managers without coupling to React or Next.js internals.
Problem Statement
VeriNode interacts with database-backed credentials and external API keys. Without rotation:
This service addresses those gaps by introducing a policy-driven rotation engine with dual-version overlap, expiry monitoring, and event-driven observability.
Architecture
Core Abstractions
SecretRotationServiceSecretStoreBackendSecretGeneratorRotationPolicyrotationIntervalMs), maximum retained versions (maxVersions), and dual-write overlap (overlapMs).RotationEventRotation Lifecycle
database-credential,api-key,token,encryption-key), an optional initial value, and a policy. The service creates the first version and schedules the next rotation.overlapMs) to allow zero-downtime cutover. Versions older than the overlap are pruned, respecting themaxVersionscap.evaluateExpiry()pass emitssecret:expiringwhen the active version enters the overlap window, andsecret:expiredwhen no valid version remains.Zero-Downtime Overlap
During rotation, both the previous and next credential are considered valid for
overlapMs. Consumers can validate against either version, enabling live cutover without downtime.Observability
rotation:started,rotation:completed,rotation:failed,secret:expiring,secret:expired,secret:revokedare emitted to registered listeners.RotationMetricsexposestotalRotations,failedRotations,activeSecrets,expiredSecrets, andlastRotationLatencyMs.Files Changed
src/types/secrets.tsSecretKind,SecretRecord,SecretVersion,RotationPolicy,RotationEvent,RotationMetrics.src/services/secretRotation.tstests/secretRotation.test.tssrc/__tests__/secretRotation.benchmark.tse2e/wallet-tests/secretRotation.spec.tswallet-ciproject, exercising the service in a real browser context.Performance
Benchmark results on Node 24:
The service is synchronous for in-memory operations, making it suitable for hot paths.
Testing Strategy
Unit Tests (
tests/secretRotation.test.ts)maxVersionsis strictly enforced after pruning.secret:expiringandsecret:expiredevents are emitted at the correct thresholds.nulland fail validation.SecretStoreBackend.Benchmark (
src/__tests__/secretRotation.benchmark.ts)Playwright E2E (
e2e/wallet-tests/secretRotation.spec.ts)wallet-ciproject alongside wallet tests.Security Considerations
SecretStoreBackend.overlapMspolicy limits the time both old and new credentials are valid.Backward Compatibility
This is a purely additive change. No existing modules, components, or tests are modified.
Checklist
npm run lintpasses (0 errors, 1 ignored-file warning)npm run buildpasses